package com.gitee.wsl.mathematics.vector.vec2

import com.gitee.wsl.mathematics.vector.Vector
import com.gitee.wsl.mathematics.vector.VectorD
import com.gitee.wsl.mathematics.vector.VectorF
import com.gitee.wsl.mathematics.vector.vec3.Vector3
import com.gitee.wsl.mathematics.vector.vec4.Vector4

typealias Vec2F = Vector2<Float,*>

typealias Vec2D = Vector2<Double,*>

interface Vector2<T:Number,V: Vector2<T, V>>: Vector<T, V> {

    val vec2 get() = this
    val vec3: Vector3<T, *>
    val vec4: Vector4<T, *>

    val x:T get() = proxy[0]

    val y:T get() = proxy[1]

    override val squaredLength get() = x * x + y * y

    override fun create(values: List<T>):V = create(values[0],values[1])

    fun create(x:T, y:T):V

    val perpendicular: V get() = create(-y, x)

    /*
    override operator fun div(other: V) :V = create(x / other.x, y / other.y)
    override operator fun times(other: V) :V = create(x * other.x, y * other.y)
    override operator fun rem(other: V) :V= create(x % other.x, y % other.y)

    override val abs get() = create(abs(x), abs(y))
    override val sign get() = create(sign(x), sign(y))
    override val ceil get() = create(ceil(x), ceil(y))
    override val floor get() = create(floor(x), floor(y))
    override val round get() = create(round(x), round(y))

    override operator fun plus(other: V) :V = create(x + other.x, y + other.y)

    override operator fun minus(other: V) :V = create(x - other.x, y - other.y)

    override operator fun times(a: Number) :V = create(x * a.toDouble(), y * a.toDouble())


    override operator fun div(a: Number) :V = create(x / a.toDouble(), y / a.toDouble())

    override fun divBy(a: Number) :V= create( x.divBy(a),  y.divBy(a))

    override operator fun rem(a: Number):V= create(x % a.toDouble(), y % a.toDouble())
    override operator fun rem(other: V) :V= create(x % other.x, y % other.y)
    override fun remBy(a: Number) :V= create( x.remBy(a),  y.remBy(a))

    override operator fun unaryMinus() : V = create(-x, -y)*/

    operator fun component1() = x
    operator fun component2() = y

}


interface Vector2F<V: Vector2<Float, V>>: Vector2<Float, V>, VectorF<V>

interface Vector2D<V: Vector2<Double, V>>: Vector2<Double, V>, VectorD<V>

